/**
 * asdlk
 */
package EstimatorPackage.Expressions;

/**
 * Class for objects representing so-called complex expression. Complex-expression are
 *  a - b
 *  a ∩ b
 *  a ∪ b
 * i.e. allways containing two expression and a operator.
 * @author Martin Haulrich
 */
public class ComplexExpression implements Expression {

    public final static int DIFFERENCE = 1;

    public final static int UNION = 2;

    public final static int INTERSECTION = 3;

    public final static int type = Expression.COMPLEX;

    public final int operation;

    public final Expression e1;

    public final Expression e2;

    final int hash;

    public ComplexExpression(int operation, Expression e1, Expression e2) {
        this.operation = operation;
        this.e1 = e1;
        this.e2 = e2;
        /**
         * @CONSIDER Is this a good hash code?
         */
        int h = 7;
        h = 83 * h + this.operation;
        h = 83 * h + (this.e1 != null ? this.e1.hashCode() : 0);
        hash = 83 * h + (this.e2 != null ? this.e2.hashCode() : 0);
    }

    @Override
    public int type() {
        return type;
    }

    @Override
    public String toString() {
        String op;
        switch (operation) {
            case DIFFERENCE:
                op = " - ";
                break;
            case UNION:
                //op = " \u222A ";
                op = " U ";
                break;
            case INTERSECTION:
                //op = " \u2229 ";
                op = " INT ";
                break;
            default:
                op = " ";
        }

        return "(" + e1 + op + e2 + ")";
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ComplexExpression other = (ComplexExpression) obj;
        if (this.operation != other.operation) {
            return false;
        }
        if ((this.e1 == other.e1 && this.e2 == other.e2) && (this.operation == UNION || this.operation == INTERSECTION)) {
            return true;
        }

        if ((this.e2 == other.e1 && this.e1 == other.e2) && (this.operation == UNION || this.operation == INTERSECTION)) {
            return true;
        }
        if (this.e1 != other.e1 && (this.e1 == null || !this.e1.equals(other.e1))) {
            return false;
        }
        if (this.e2 != other.e2 && (this.e2 == null || !this.e2.equals(other.e2))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {

        return hash;
    }
//    @Override
//    public boolean equals(Object o) {
//        if (o instanceof ComplexExpression) {
//            ComplexExpression ce = (ComplexExpression) o;
//            //boolean eq = ((ce.operation == operation) && (ce.e1 == e1) && (ce.e2 == e2));
//            //System.err.println("CompExp: " + ce + " : " + this + "   " + eq);
//            return ((ce.operation == operation) && (ce.e1.equals(e1)) && (ce.e2.equals(e2)));
//        }
//        return false;
//    }
//
//
//    @Override
//    public int hashCode() {
//        return hash;
//    }
}
